/*
 * Copyright (c) 2018-2999 九五云信息科技有限公司 All rights reserved.
 *
 * https://www.gz-yami.com/
 *
 * 未经允许，不可做商业用途！
 *
 * 版权所有，侵权必究！
 */

package com.yami.shop.discount.api.listener;

import com.yami.shop.bean.app.dto.ChooseDiscountItemDto;
import com.yami.shop.bean.app.dto.ShopCartItemDiscountDto;
import com.yami.shop.bean.app.dto.ShopCartItemDto;
import com.yami.shop.bean.app.dto.ShopCartOrderDto;
import com.yami.shop.bean.enums.DiscountRule;
import com.yami.shop.bean.enums.DiscountType;
import com.yami.shop.bean.event.ConfirmOrderEvent;
import com.yami.shop.bean.order.ConfirmOrderOrder;
import com.yami.shop.common.util.Arith;
import lombok.AllArgsConstructor;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 确认订单信息时监听事件
 * @author LGH
 */
@Component("discountConfirmOrderListener")
@AllArgsConstructor
public class ConfirmOrderListener {

    /**
     * 确认订单信息时的满减满折的相关操作，计算满减折 优惠金额
     */
    @EventListener(ConfirmOrderEvent.class)
    @Order(ConfirmOrderOrder.DISCOUNT)
    public void discountConfirmOrderEvent(ConfirmOrderEvent event) {
        ShopCartOrderDto shopCartOrderDto = event.getShopCartOrderDto();

        List<ShopCartItemDiscountDto> shopCartItemDiscounts = shopCartOrderDto.getShopCartItemDiscounts();
        // 如果是预售订单则不能使用优惠
        if(Objects.equals(event.getOrderParam().getPreSellStatus(),1)){
            return;
        }
        double reduce = 0.0;
        for (ShopCartItemDiscountDto shopCartItemDiscount : shopCartItemDiscounts) {
            ChooseDiscountItemDto chooseDiscountItemDto = shopCartItemDiscount.getChooseDiscountItemDto();
            if(Objects.isNull(chooseDiscountItemDto)){
                continue;
            }
            // 如果不满足满钱优惠活动，则跳过
            if ( Objects.equals(chooseDiscountItemDto.getDiscountRule(), DiscountRule.M2M.value()) &&
                    Objects.equals(chooseDiscountItemDto.getDiscountRule(), DiscountRule.M2D.value()) &&
                            chooseDiscountItemDto.getNeedAmount() > chooseDiscountItemDto.getProdsPrice()) {
                continue;
            }
            // 如果不满足满件优惠活动，则跳过
            if ( Objects.equals(chooseDiscountItemDto.getDiscountRule(), DiscountRule.P2M.value()) &&
                    Objects.equals(chooseDiscountItemDto.getDiscountRule(), DiscountRule.P2D.value()) &&
                            chooseDiscountItemDto.getNeedAmount() > chooseDiscountItemDto.getProdCount()) {
                continue;
            }

            // 计算分摊金额
            List<ShopCartItemDto> shopCartItems = shopCartItemDiscount.getShopCartItems();

            double discountAmount = 0.00;
            double reduceAmount = Arith.round(chooseDiscountItemDto.getReduceAmount(),2);
            reduce = Arith.add(reduce, reduceAmount);
            shopCartItems = shopCartItems.stream().sorted(Comparator.comparingDouble(ShopCartItemDto::getActualTotal).reversed()
            ).collect(Collectors.toList());
//            for (ShopCartItemDto shopCartItem : shopCartItems) {
            for (int index = 0; index < shopCartItems.size(); index++) {
                ShopCartItemDto shopCartItem = shopCartItems.get(index);

                double shareReduce;
                if(index + 1 == shopCartItems.size()){
                    shareReduce = Arith.sub(reduceAmount,discountAmount);
                }else {
                    // 分摊金额 = 该优惠活动优惠金额 * (商品金额 / 参与该活动的商品总金额)
                    shareReduce = Arith.round(Arith.mul(chooseDiscountItemDto.getReduceAmount(), Arith.div(shopCartItem.getProductTotalAmount(),
                            chooseDiscountItemDto.getProdsPrice())),2);
                }
                shopCartItem.setShareReduce(shareReduce);
                shopCartItem.setActualTotal(Arith.sub(shopCartItem.getActualTotal(),shareReduce));
                discountAmount = Arith.add(discountAmount,shareReduce);
            }

            //若分摊金额的总数不等于满减金额，则在金额最大的订单减去差价
            if (!Objects.equals(discountAmount,reduceAmount)){
                List<ShopCartItemDto> collectDesc = shopCartItems.stream().sorted(Comparator.comparingDouble(ShopCartItemDto::getActualTotal).reversed()
                ).collect(Collectors.toList());
                ShopCartItemDto shopCartItemDto = collectDesc.get(0);
                double changeAmount = Arith.sub(reduceAmount,discountAmount);
                shopCartItemDto.setActualTotal(Arith.add(shopCartItemDto.getActualTotal(),changeAmount));
                shopCartItemDto.setShareReduce(Arith.add(shopCartItemDto.getShareReduce(),changeAmount));
            }
        }

        shopCartOrderDto.setActualTotal(Arith.sub(shopCartOrderDto.getActualTotal(), reduce));
        shopCartOrderDto.setDiscountReduce(reduce);
        shopCartOrderDto.setShopReduce(Arith.add(shopCartOrderDto.getShopReduce(), reduce));
    }
}
